fix(analyzer): order NAT Gateway deletion before IGW / VPCGatewayAttachment on destroy - #823
Merged
Conversation
Destroying a VPC + NAT Gateway + IGW stack attempted the VPCGatewayAttachment detach while the NAT Gateway's Elastic IP was still mapped to the VPC's public address space, failing with "Network vpc-xxx has some mapped public address(es)", after which the IGW delete hung (~19 min observed). This was the first-run failure split out of the #804 incident as a separate issue. Add two type-based implicit delete-dependency edges in IMPLICIT_DELETE_DEPENDENCIES so the shared deploy DELETE phase and the standalone destroy command order the teardown like CloudFormation does: - AWS::EC2::InternetGateway now lists AWS::EC2::NatGateway (alongside its existing AWS::EC2::VPCGatewayAttachment dependee) - AWS::EC2::VPCGatewayAttachment (new key) lists AWS::EC2::NatGateway Both are deleted AFTER the NAT Gateway is gone, since NAT deletion releases/decouples the EIP. No type-based rule is needed for the EIP itself: the NAT Ref's its EIP via AllocationId, so the reversed delete traversal already deletes the NAT before the EIP is released. The injection logic naturally produces no edge when no NatGateway is in state. Tests: 4 unit assertions in implicit-delete-deps.test.ts (IGW-after-NAT edge, VPCGatewayAttachment-after-NAT edge, no NatGateway/EIP key registered; the existing no-self-cycle guard covers the new entries). The existing vpc-nat-gateway integ fixture (VPC + public/private subnets + IGW + NatGateway + EIP) exercises this teardown end-to-end. Closes #817
go-to-k
force-pushed
the
fix/817-igw-nat-delete-dep
branch
from
June 13, 2026 06:12
91a87ce to
2eda56d
Compare
github-actions Bot
pushed a commit
that referenced
this pull request
Jun 13, 2026
## [0.220.3](v0.220.2...v0.220.3) (2026-06-13) ### Bug Fixes * **analyzer:** order NAT Gateway deletion before IGW / VPCGatewayAttachment on destroy ([#823](#823)) ([cbeb742](cbeb742))
|
🎉 This PR is included in version 0.220.3 🎉 The release is available on: Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Destroying a VPC + NAT Gateway + IGW stack attempted the
VPCGatewayAttachmentdetach while the NAT Gateway's Elastic IP was still mapped →Network vpc-xxx has some mapped public address(es), after which the IGW delete hung (~19 min observed). This is an implicit delete-dependency gap: IGW detach/delete must wait for NAT Gateway deletion (which releases/decouples the EIP) first.Fix
Added to
IMPLICIT_DELETE_DEPENDENCIESinsrc/analyzer/implicit-delete-deps.ts:AWS::EC2::InternetGateway→AWS::EC2::NatGateway(alongside the existingVPCGatewayAttachment)AWS::EC2::VPCGatewayAttachment→AWS::EC2::NatGateway(new key)The map KEY is deleted after the listed types: the consumer injects
DependsOn: [<key>]on each NatGateway, and the reversed destroy traversal deletes NAT first — matching CloudFormation's NAT-before-IGW ordering. These edges are consumed only in delete-scoped structures (addImplicitDeleteDependencies/ the reverse-DAG destroy traversal), so create ordering is unaffected. EIP needs no rule — NAT references its EIP viaFn::GetAtt[EIP, AllocationId], so the existing reference-based reversed-delete already deletes NAT before EIP release.Test plan
tests/unit/analyzer/implicit-delete-deps.test.ts): the IGW/VPCGatewayAttachment→NatGateway edges are produced; NatGateway/EIP are never KEYs (no outbound implicit edge); the no-self-cycle guard covers the new keys.vpc-nat-gateway: VPC + 4 subnets + IGW + VPCGatewayAttachment + NAT + EIP + routes): deploy + destroy clean — 21 deleted, 0 errors, 0 orphans, with NAT deleted before the IGW/EIP. Pre-fix this destroy failed on the mapped-address error + IGW hang.Independent review
Code review clean — verified edge direction, no create-ordering side-effect (delete-only consumption), the EIP reference-ordering claim, and no cycle introduced.
Closes #817